package dalex.world;

import java.io.File;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import dalex.player.Monster;
import dalex.player.Player;

public class Map {
	private Site[][] map;
	private String name;
	private Position mapPos;
	private Object lock;
	private String url;
	
	public Map(){
		mapPos = new Position(-1,-1,-1);
	}
	
	public Map(String url){
		this.url = url;
	}
	
	public void setMap(){
		try{
			if(lock == null){
				SAXParserFactory factory = SAXParserFactory.newInstance();
				SAXParser parser = factory.newSAXParser();
				
				MapHandler handler = new MapHandler();
				parser.parse(new File(url), handler);
				map = handler.getMap();
				name = handler.getMapName();
				mapPos = handler.getMapPostion();
				
				lock = new Object();
				System.out.println(name+"地图创建成功！");
			}else{
				System.out.println(name+"地图已经创建过！");
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public Site getSite(Position pos){
		for(int i = 0 ; i < map.length ; i++){
			for(int j = 0; j < map[i].length ; j++){
				if(map[i][j].getPosition().equals(pos)){
					return map[i][j];
				}
			}
		}
		return null;
	}
	
	public void showTheMap(){
		if(lock == null){
			System.out.println("地图尚未创建！");
		}else{
			for(int i = map.length - 1; i>=0 ; i--){
				for(int j = 0; j < map[i].length ; j++){
					if(map[i][j] != null){
						System.out.print("*");
					}else{
						System.out.print(" ");
					}
				}
				System.out.print("\n");
			}
		}
	}

	public String getName(){
		return name;
	}
	
	public Position getMapPosition(){
		return mapPos;
	}
	
	public void addPlayer(Player player,Position pos){
		this.map[pos.getX()][pos.getY()].addPlayer(player.getName(), player);
	}
	
	public void movePlayer(Player player,Position pos){
		Position prePos = player.getPosition();
		this.map[pos.getX()][prePos.getY()].removePlayer(player.getName());
		addPlayer(player,pos);
	}
}

class MapHandler extends DefaultHandler{
	private Stack<String> stack = new Stack<String>();
	private String type;
	private String name;
	private String position;
	private String value;
	private Site[][] map;
	private String mapName;
	private Position mapPos;
	
	public String getMapName(){
		return mapName;
	}
	
	public Site[][] getMap(){
		return map;
	}
	
	public Position getMapPostion(){
		return mapPos;
	}
	
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException{
		stack.push(qName);
		
		for(int i = 0; i < attributes.getLength(); i++){
			String attrName = attributes.getQName(i);
			String attrValue = attributes.getValue(i);
			System.out.println(attrName + "=" + attrValue);
		}
	}
	
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException{
		String tag = stack.peek();
		
		if("type".equals(tag)){
			type = new String(ch, start,length);
		}
		else if("name".equals(tag)){
			name = new String(ch, start, length);
		}
		else if("position".equals(tag)){
			position = new String(ch, start, length);
		}else if("value".equals(tag)){
			value = new String(ch, start, length);
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException{
		stack.pop(); //表示该元素已经解析完毕，需要从栈中弹出
		
		if("node".equals(qName)){
			System.out.println("type：" + type);
			System.out.println("name：" + name);
			System.out.println("position：" + position);
			System.out.println("value：" + value);
			System.out.println();
			
			if(type.equals("description")){
				mapName = value;
				
			}else if(type.equals("position")){
				int z = Integer.parseInt(value);
				int x = Integer.parseInt(position.split(",")[0]);
				int y = Integer.parseInt(position.split(",")[1]);
				mapPos = new Position(x,y,z);
				
			}else if(type.equals("size")){
				int x = Integer.parseInt(value.split(",")[0]);
				int y = Integer.parseInt(value.split(",")[1]);
				map = new Site[x][y];
				
				for(int i = 0 ; i < map.length ; i++){
					for(int j = 0; j < map[i].length ; j++){
						map[i][j] = new Site("null",new Position(-1,-1,-1));
					}
				}
				
				
			}else if(type.equals("site")){
				int x = Integer.parseInt(position.split(",")[0]);
				int y = Integer.parseInt(position.split(",")[1]);
				
				Site tempSite = new Site(name,new Position(x,y,mapPos.getMapID()));
				tempSite.setDescription(value);
				map[x][y] = tempSite;
				
			}else if(type.equals("NPC")){
				int x = Integer.parseInt(position.split(",")[0]);
				int y = Integer.parseInt(position.split(",")[1]);
				
				NPC npc = new NPC();
				//map[x][y].addNPC(npc.getName(), npc);
			}
		}
		
	}
}